﻿Imports System
Imports System.Collections.Generic
Imports System.Workflow.ComponentModel

Namespace System.Workflow.Activities
    Friend Class StateMachineHelpers
        ' Methods
        Friend Shared Function ContainsEventActivity(ByVal compositeActivity As CompositeActivity) As Boolean
            Dim queue As New Queue([Of] Activity)
            queue.Enqueue(compositeActivity)
            Do While (queue.Count > 0)
                Dim activity As Activity = queue.Dequeue
                If TypeOf activity Is IEventActivity Then
                    Return True
                End If
                compositeActivity = [TryCast](activity,CompositeActivity)
                If (Not compositeActivity Is Nothing) Then
                    Dim activity2 As Activity
                    For Each activity2 In compositeActivity.Activities
                        If activity2.Enabled Then
                            queue.Enqueue(activity2)
                        End If
                    Next
                End If
            Loop
            Return False
        End Function

        Friend Shared Function ContainsState(ByVal state As StateActivity, ByVal stateName As String) As Boolean
            If (state Is Nothing) Then
                Throw New ArgumentNullException("state")
            End If
            If String.IsNullOrEmpty(stateName) Then
                Throw New ArgumentNullException("stateName")
            End If
            Dim queue As New Queue([Of] StateActivity)
            queue.Enqueue(state)
            Do While (queue.Count > 0)
                state = queue.Dequeue
                If state.QualifiedName.Equals(stateName) Then
                    Return True
                End If
                Dim activity As Activity
                For Each activity In state.EnabledActivities
                    Dim item As StateActivity = [TryCast](activity,StateActivity)
                    If (Not item Is Nothing) Then
                        queue.Enqueue(item)
                    End If
                Next
            Loop
            Return False
        End Function

        Friend Shared Function FindActivityByName(ByVal parentActivity As CompositeActivity, ByVal qualifiedName As String) As Activity
            Return parentActivity.GetActivityByName(qualifiedName, True)
        End Function

        Friend Shared Function FindDynamicStateByName(ByVal state As StateActivity, ByVal stateQualifiedName As String) As StateActivity
        Label_0061:
            Do While (Not state.QualifiedName.Equals(stateQualifiedName) AndAlso StateMachineHelpers.ContainsState(state, stateQualifiedName))
                Dim activity As Activity
                For Each activity In state.EnabledActivities
                    Dim activity2 As StateActivity = [TryCast](activity,StateActivity)
                    If ((Not activity2 Is Nothing) AndAlso StateMachineHelpers.ContainsState(activity2, stateQualifiedName)) Then
                        Dim dynamicActivity As StateActivity = DirectCast(state.GetDynamicActivity(activity2.QualifiedName), StateActivity)
                        If (dynamicActivity Is Nothing) Then
                            Return Nothing
                        End If
                        state = dynamicActivity
                        goto Label_0061
                    End If
                Next
            Loop
            If state.QualifiedName.Equals(stateQualifiedName) Then
                Return state
            End If
            Return Nothing
        End Function

        Friend Shared Function FindEnclosingState(ByVal activity As Activity) As StateActivity
            Dim activity2 As StateActivity = [TryCast](activity,StateActivity)
            If (Not activity2 Is Nothing) Then
                Return activity2
            End If
            If (activity.Parent Is Nothing) Then
                Return Nothing
            End If
            Return StateMachineHelpers.FindEnclosingState(activity.Parent)
        End Function

        Friend Shared Function FindStateByName(ByVal state As StateActivity, ByVal qualifiedName As String) As StateActivity
            Return [TryCast](StateMachineHelpers.FindActivityByName(state, qualifiedName),StateActivity)
        End Function

        Friend Shared Function GetCompletedStateName(ByVal state As StateActivity) As String
            Return CStr(StateMachineHelpers.GetRootState(state).GetValue(StateMachineWorkflowActivity.CompletedStateNameProperty))
        End Function

        Friend Shared Function GetCurrentState(ByVal context As ActivityExecutionContext) As StateActivity
            Dim state As StateActivity = [TryCast](context.Activity,StateActivity)
            If (state Is Nothing) Then
                state = StateMachineHelpers.FindEnclosingState(context.Activity)
            End If
            Dim rootState As StateActivity = StateMachineHelpers.GetRootState(state)
            Dim currentStateName As String = StateMachineExecutionState.Get(rootState).CurrentStateName
            If (currentStateName Is Nothing) Then
                Return Nothing
            End If
            Return StateMachineHelpers.FindDynamicStateByName(rootState, currentStateName)
        End Function

        Friend Shared Function GetEventActivity(ByVal eventDriven As EventDrivenActivity) As IEventActivity
            Dim activity As CompositeActivity = eventDriven
            Return [TryCast](activity.EnabledActivities.Item(0),IEventActivity)
        End Function

        Friend Shared Function GetInitialStateName(ByVal state As StateActivity) As String
            Return CStr(StateMachineHelpers.GetRootState(state).GetValue(StateMachineWorkflowActivity.InitialStateNameProperty))
        End Function

        Friend Shared Function GetParentEventDriven(ByVal eventActivity As IEventActivity) As EventDrivenActivity
            Dim activity As Activity = DirectCast(eventActivity, Activity).Parent
            Do While (Not activity Is Nothing)
                Dim activity2 As EventDrivenActivity = [TryCast](activity,EventDrivenActivity)
                If (Not activity2 Is Nothing) Then
                    Return activity2
                End If
                activity = activity.Parent
            Loop
            Return Nothing
        End Function

        Friend Shared Function GetRootState(ByVal state As StateActivity) As StateActivity
            If ((Not state.Parent Is Nothing) AndAlso TypeOf state.Parent Is StateActivity) Then
                Return StateMachineHelpers.GetRootState(DirectCast(state.Parent, StateActivity))
            End If
            Return state
        End Function

        Friend Shared Function IsCompletedState(ByVal state As StateActivity) As Boolean
            Dim completedStateName As String = StateMachineHelpers.GetCompletedStateName(state)
            If (completedStateName Is Nothing) Then
                Return False
            End If
            Return state.QualifiedName.Equals(completedStateName)
        End Function

        Friend Shared Function IsInitialState(ByVal state As StateActivity) As Boolean
            Dim initialStateName As String = StateMachineHelpers.GetInitialStateName(state)
            If (initialStateName Is Nothing) Then
                Return False
            End If
            Return state.QualifiedName.Equals(initialStateName)
        End Function

        Friend Shared Function IsLeafState(ByVal state As StateActivity) As Boolean
            If (state Is Nothing) Then
                Throw New ArgumentNullException("state")
            End If
            If StateMachineHelpers.IsRootState(state) Then
                Return False
            End If
            Dim activity As Activity
            For Each activity In state.EnabledActivities
                If TypeOf activity Is StateActivity Then
                    Return False
                End If
            Next
            Return True
        End Function

        Friend Shared Function IsRootExecutionContext(ByVal context As ActivityExecutionContext) As Boolean
            Return (context.Activity.Parent Is Nothing)
        End Function

        Friend Shared Function IsRootState(ByVal state As StateActivity) As Boolean
            If (state Is Nothing) Then
                Throw New ArgumentNullException("state")
            End If
            Dim parent As StateActivity = [TryCast](state.Parent,StateActivity)
            Return (parent Is Nothing)
        End Function

        Friend Shared Function IsStateMachine(ByVal state As StateActivity) As Boolean
            If (state Is Nothing) Then
                Throw New ArgumentNullException("state")
            End If
            Return TypeOf state Is StateMachineWorkflowActivity
        End Function

    End Class
End Namespace

